#include"LogParser.h"
#include<pugixml.hpp>
#include"TypeConverter.h"
#include "LogExecuter.h"
FunctionCall LogParser::parseXmlStrToCall(std::string xmlStr)
{
	pugi::xml_document doc;
	doc.load_string(xmlStr.c_str());
	FunctionCall call;

	pugi::xml_node funcNode = doc.child("Function");
	std::string callName = funcNode.attribute("name").value();
	callName=TypeConverter::trimSpaceTwoSides(callName);
	call.name = callName;

	std::string callAction = funcNode.attribute("action").value();
	callAction = TypeConverter::trimSpaceTwoSides(callAction);
	call.action = callAction;

	std::string callTime = funcNode.attribute("time").value();
	callTime = TypeConverter::trimSpaceTwoSides(callTime);
	call.time = callTime;

	Parameter para;
	for (pugi::xml_node parameterNode : funcNode.children("Parameter")) {
		std::string paraName = parameterNode.attribute("name").value();
		paraName = TypeConverter::trimSpaceTwoSides(paraName);
		para.name = paraName;

		std::string paraType = parameterNode.child("type").text().get();
		paraType = TypeConverter::trimAllSpaces(paraType);
		para.type = paraType;

		std::string paraValue = parameterNode.child("value").text().get();
		paraValue = TypeConverter::trimSpaceTwoSides(paraValue);
		para.stringValue = paraValue;

		if (call.action == "enter") {
			para.value = TypeConverter::strFormatValConvertToPara(para.type, para.stringValue);
			if (para.type == "constchar*[]" || para.type == "strings" || para.type == "doubles" || para.type == "ints" || para.type == "double[]" || para.type == "int[]") {
				para.size=TypeConverter::getElementsCountOfStr(para.stringValue);
			}
		}
		call.parameters.push_back(para);
	}
	if (maxParasSize < call.parameters.size()) {
		maxParasSize = static_cast<int>(call.parameters.size());
	}
	return call;
}

std::vector<std::string>& LogParser::getXmlStrs()
{
	return xmlStrs;
}

std::vector<FunctionCall>& LogParser::getCalls()
{
	return calls;
}



std::vector<FunctionCall>& LogParser::parseLogFileToCalls(std::string logFilePath)
{
	std::ifstream fileIn(logFilePath);
	if (!fileIn.is_open()) {
		throw std::runtime_error("file is not exist or using now");
	}
	std::string lineText;
	std::string xmlText;
	bool isTail = false;
	while (std::getline(fileIn, lineText)) {
		if (lineText.find("<Function") != std::string::npos) {
			isTail = false;
			xmlText += lineText;
			xmlText.push_back('\n');
		}
		else if (!isTail) {
			xmlText += lineText;
			xmlText.push_back('\n');
			if (lineText.find("</Function") != std::string::npos) {
				isTail = true;
				FunctionCall call = parseXmlStrToCall(xmlText);
				calls.push_back(call);
				xmlStrs.push_back(xmlText);
				xmlText.clear();
			}
		}
	}
	if (calls.size() % 2 != 0) {
		std::string errorMessage = "XML number:" + std::to_string(calls.size()) + ",is not correct";
		throw std::runtime_error(errorMessage);
	}
	return calls;
}

void LogParser::setParserCalls(std::vector<FunctionCall> calls)
{
	this->calls = calls;
}

int LogParser::getMaxParasSize()
{
	return maxParasSize;
}